package com.example.my.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.my.entity.User;
import com.example.my.mapper.UserMapper;
import com.example.my.service.UserService;
import com.example.my.util.RedisUtil;
import com.example.my.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private TokenUtil tokenUtil;


    @Override
    public boolean register(User user) {
        // 1. 查重：username、email
        if (this.count(new QueryWrapper<User>().eq("username", user.getUsername())) > 0) {
            throw new IllegalArgumentException("用户名已存在，请替换其它用户名！");
        }
        if (this.count(new QueryWrapper<User>().eq("email", user.getEmail())) > 0) {
            throw new IllegalArgumentException("邮箱已被注册！");
        }

        // 2. 密码非空校验
        if (user.getPassword() == null || user.getPassword().isBlank()) {
            throw new IllegalArgumentException("密码不能为空！");
        }

        // 3. 密码加密（MD5）
        String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pwd);

        // 4. 入库
        return this.save(user);
    }

    @Override
    public String login(String username, String password) {
        // 1. 非空校验
        if (org.springframework.util.StringUtils.isEmpty(username)
                || org.springframework.util.StringUtils.isEmpty(password)) {
            throw new IllegalArgumentException("用户名或者密码不能为空！");
        }

        // 2. 构造查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username)
                .eq("password", DigestUtils.md5DigestAsHex(password.getBytes()))
                .eq("status", 1);   // 1 = 正常在用

        // 3. 执行查询
        User user = this.getOne(queryWrapper);
        if (user == null) {
            throw new IllegalArgumentException("用户名或密码错误，请查证后重新操作！");
        }
        // 1. 生成 token
        String token = tokenUtil.generateToken();

// 2. 缓存两份映射，均设 30 分钟过期
        String tokenKey = "user:token:" + token;
        String idKey   = "user:id:"   + user.getId();

        redisUtil.set(tokenKey, user.getId(), 30L, TimeUnit.MINUTES);
        redisUtil.set(idKey,    token,        30L, TimeUnit.MINUTES);

        return token;
    }

    @Override
    public User getUserByToken(String token) {
        // 1. token 格式校验
        if (!tokenUtil.validateToken(token)) {
            return null;
        }

        // 2. 从 Redis 取用户 ID
        Object userIdObj = redisUtil.get("user:token:" + token);
        if (userIdObj == null) {
            return null;
        }

        try {
            Long userId = Long.valueOf(userIdObj.toString());
            // 3. 查库
            User user = this.getById(userId);
            return user;          // 可能为 null，调用方再判断
        } catch (NumberFormatException e) {
            // Redis 数据被污染，返回 null 即可
            return null;
        }
    }

    @Override
    public boolean logout(String token) {
        User user = getUserByToken(token);
        if (user != null) {
            // 同时删除两份缓存
            redisUtil.delete("user:token:" + token);
            redisUtil.delete("user:id:" + user.getId());
            return true;
        }
        return false;
    }


}